package shudu;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Draft extends Chessboard {

	private DraftCell[][] draftCells;

	int doneCount = 0;

	private ArrayList<Group> groups = new ArrayList<Draft.Group>();

	class Group {
		int count = 0;

		protected void addCell(DraftCell cell) {
			if (cell.getNumber() == null) {
				emptyCell.add(cell);
			} else {
				doneCell.add(cell);
				hasResult.add(cell.getNumber());
			}
		}
		
		protected void refresh() {
			for (Iterator<DraftCell> iterator = emptyCell.iterator(); iterator
					.hasNext();) {
				DraftCell draftCell = iterator.next();
				if(draftCell.getNumber() != null) {
					iterator.remove();
					doneCell.add(draftCell);
					hasResult.add(draftCell.number);
				}
			}
		}

		List<DraftCell> doneCell = new ArrayList<DraftCell>(9);
		List<Integer> hasResult = new ArrayList<Integer>(9);
		List<DraftCell> emptyCell = new LinkedList<DraftCell>();
	}

	public Draft(Chessboard chessboard) {
		super(chessboard.cells);
		draftCells = new DraftCell[chessboard.getHeight()][];
		for (int i = 0; i < chessboard.getHeight(); i++) {
			draftCells[i] = new DraftCell[chessboard.getWidth()];
			for (int j = 0; j < chessboard.getWidth(); j++) {
				addCellAt(chessboard.getCell(i, j), i, j);
			}
		}

		for (int i = 0; i < chessboard.getHeight(); i++) {
			Group group = new Group();
			for (int j = 0; j < chessboard.getWidth(); j++) {
				group.addCell(draftCells[i][j]);
			}
			groups.add(group);
		}

		for (int i = 0; i < chessboard.getHeight(); i++) {
			Group group = new Group();
			for (int j = 0; j < chessboard.getWidth(); j++) {
				group.addCell(draftCells[j][i]);
			}
			groups.add(group);
		}

		Group[] g = new Group[9];
		for (int i = 0; i < chessboard.getHeight(); i++) {
			Group group = new Group();
			for (int j = 0; j < chessboard.getWidth(); j++) {
				group = g[((i / 3) * 3) + (j / 3)];
				if (group == null) {
					group = new Group();
					g[((i / 3) * 3) + (j / 3)] = group;
				}
				group.addCell(draftCells[j][i]);
			}
			groups.add(group);
		}
	}

	public void addCellAt(Cell cell, int x, int y) {
		draftCells[x][y] = new DraftCell(cell);
		draftCells[x][y].x = y;
		draftCells[x][y].y = x;
		if (draftCells[x][y].getNumber() != null) {
			doneCount++;
		}
	}

	public DraftCell getCell(int x, int y) {
		return draftCells[x][y];
	}

	public void checkAll() {
		for (Iterator<Group> it = groups.iterator(); it.hasNext();) {
			Group group = it.next();
			group.refresh();
			if(group.doneCell.size() == 9) {
				it.remove();
			}else {
				while (true) {
					
					boolean getNew = false;
					
					for (Iterator<DraftCell> iterator = group.emptyCell.iterator(); iterator
							.hasNext();) {
						DraftCell draftCell = iterator.next();
						if(draftCell.x == 5 && draftCell.y == 7) {
							System.out.println("aaa");
						}
						
						draftCell.mayNumber.removeAll(group.hasResult);

						if (draftCell.hasResult()) {
							draftCell.done();
							
							iterator.remove();
							group.doneCell.add(draftCell);
							group.hasResult.add(draftCell.getNumber());
							
							doneCount++;
							getNew = true;
						}
					}
					
					//检查是否存在某个可能的值是否仅仅在一个空格中出现过，如果是则该空格必定为该值
					for (Iterator<DraftCell> iterator = group.emptyCell.iterator(); iterator
							.hasNext();) {
						DraftCell draftCell = iterator.next();
						
						LinkedList<Integer> mayNumber = (LinkedList<Integer>) draftCell.mayNumber.clone();
						for(DraftCell other : group.emptyCell) {
							if(!draftCell.equals(other)) {
								mayNumber.removeAll(other.mayNumber);
								if(mayNumber.size() == 0) {
									break;
								}
							}
						}
						if(mayNumber.size() > 0) {
							draftCell.setNumber(mayNumber.getFirst());
							System.out.println("get number at x=" + (draftCell.x + 1) + ",y=" + (draftCell.y + 1)
									+ ",value = " + draftCell.getNumber());
							iterator.remove();
							group.doneCell.add(draftCell);
							group.hasResult.add(draftCell.getNumber());
							
							doneCount++;
							getNew = true;
						}
					}

					if (!getNew) {
						break;
					}
				}
			}
		}
	}
	
	public String toString() {
		StringBuilder sb = new StringBuilder();
		int count = 0;
		for(int i = 0 ; i < cells.length ; i++) {
			if(i%3 == 0) {
				sb.append("===================================\n");
			}
			
			for(int j = 0 ; j < cells.length ; j++) {
				DraftCell draftCell = getCell(i, j);
				if(getCell(i, j).getNumber() != null) {
					count++;
				}
				if (j%3 == 0) {
					sb.append("||");
				}
				else {
					sb.append("|");
				}
				
				if(draftCell.getNumber() == null) {
					for(int t = 1; t < 4 ; t++) {
						if(draftCell.mayNumber.contains(t)) {
							sb.append(t);
						}
						else {
							sb.append(" ");
						}
					}
				}
				else {
					sb.append("---");
				}
//				sb.append((getCell(i, j).getNumber() == null ? " " : getCell(i, j).getNumber()) + " ");
				if (j == cells.length -1) {
					sb.append("||");
				}
			}
			sb.append("\n");
			for(int j = 0 ; j < cells.length ; j++) {
				DraftCell draftCell = getCell(i, j);
				if(getCell(i, j).getNumber() != null) {
					count++;
				}
				if (j%3 == 0) {
					sb.append("||");
				}
				else {
					sb.append("|");
				}
				
				if(draftCell.getNumber() == null) {
					for(int t = 4; t < 7 ; t++) {
						if(draftCell.mayNumber.contains(t)) {
							sb.append(t);
						}
						else {
							sb.append(" ");
						}
					}
				}
				else {
					sb.append("|"+draftCell.getNumber()+"|");
				}
//				sb.append((getCell(i, j).getNumber() == null ? " " : getCell(i, j).getNumber()) + " ");
				if (j == cells.length -1) {
					sb.append("||");
				}
			}
			sb.append("\n");
			for(int j = 0 ; j < cells.length ; j++) {
				DraftCell draftCell = getCell(i, j);
				if(getCell(i, j).getNumber() != null) {
					count++;
				}
				if (j%3 == 0) {
					sb.append("||");
				}
				else {
					sb.append("|");
				}
				
				
				if(draftCell.getNumber() == null) {
					for(int t = 7; t < 10 ; t++) {
						if(draftCell.mayNumber.contains(t)) {
							sb.append(t);
						}
						else {
							sb.append(" ");
						}
					}
				}
				else {
					sb.append("---");
				}
//				sb.append((getCell(i, j).getNumber() == null ? " " : getCell(i, j).getNumber()) + " ");
				if (j == cells.length -1) {
					sb.append("||");
				}
			}
			sb.append("\n");
			if(i == cells.length -1) {
				sb.append("===================================\n");
			}
		}
		sb.append("find count " + count);
		return sb.toString();
	}
}
